package top.chmin.project.cloud.code;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.chmin.project.cloud.sys.table.info.TableInfo;
import top.chmin.project.cloud.tool.DatetimeTool;
import top.chmin.project.cloud.tool.SpringTool;

import java.io.File;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * chmin
 * 2024/1/10 15:58
 * cloud-builder
 */
public interface Builder2 {

    Logger log = LoggerFactory.getLogger(Builder2.class);

    static String fix(BuildData2 data, String source) {
        source = source
                .replace("#s.now", DatetimeTool.format(LocalDateTime.now()))
                .replace("#c.javaPath", data.configInfo.getJavaPath())
                .replace("#c.vuePath", data.configInfo.getVuePath())
                .replace("#t.tableName", data.tableInfo.getTableName())
                .replace("#t.tableComment", data.tableInfo.getTableComment())
                .replace("#t.moduleName", getModuleName(data.tableInfo))
                .replace("#t.modelName", getModelName(data.tableInfo))
                .replace("#t.className", getClassName(data.tableInfo))
                .replace("#t.modulePath", getModelPath(data.tableInfo))
                .replace("#t.relatePath", getRelatePath(data.tableInfo))
                .replace("#t.fieldName", getFieldName(data.tableInfo));
        return source;
    }

    static String getModuleName(TableInfo tableInfo) {
        return tableInfo.getTableName().replace("_", ".");
    }

    static String getModelName(TableInfo tableInfo) {
        return StringUtils.capitalize(getFieldName(tableInfo));
    }

    static String getClassName(TableInfo tableInfo) {
        return "top.chmin.project.cloud." + tableInfo.getPrefix().replace("_", ".") + "." + getModelName(tableInfo);
    }

    static String getModelPath(TableInfo tableInfo) {
        return tableInfo.getTableName().replace("_", "\\");
    }

    static String getRelatePath(TableInfo tableInfo) {
        return Stream.of(tableInfo.getTableName().split("_")).map(s -> "../").collect(Collectors.joining());
    }

    static String getFieldName(TableInfo tableInfo) {
        return StrUtil.toCamelCase(tableInfo.getTableName().replace(tableInfo.getPrefix(), ""));
    }

    void build(BuildData2 buildData);

    default void save(BuildData2 buildData, String filePath, String content) {
        filePath = fix(buildData, filePath);
        content = fix(buildData, content);
        File file = new File(filePath);
        log.info("filePath: {}", filePath);
        if (!file.exists() || buildData.overwrite) {
            // 保存
            FileUtil.writeString(content, file, "UTF-8");
        } else {
            String oldContent = FileUtil.readString(file, Charset.defaultCharset());
            if (!oldContent.contains("/* append")) {
                FileUtil.writeString(content, file, "UTF-8");
            }
        }
        List<String> lines = FileUtil.readLines(file, "UTF-8");
        boolean auto = false;
        List<String> temp = new ArrayList<>();
        for (String s : lines) {
            if (s.trim().startsWith("/*自动代码开始，自定义代码请写在区域外*/")) {
                auto = true;
                continue;
            }
            if (s.trim().startsWith("/*自动代码结束，自定义代码请写在区域外*/")) {
                auto = false;
                continue;
            }
            if (s.trim().startsWith("import ")) {
                continue;
            }
            if (!auto) {
                temp.add(s);
            }
        }
        lines = temp;
        List<String> result = new ArrayList<>();
        for (String line : lines) {
            if (line.trim().startsWith("/* append")) {
                String beanName = line.substring(line.indexOf("$"));

                beanName = beanName.substring(1, beanName.indexOf("$", 1));

                BuilderAppender2 handler = (BuilderAppender2) SpringTool.getBeanByName(beanName);

                temp = handler.append(buildData);
                if (!temp.isEmpty()) {
                    result.add("/*自动代码开始，自定义代码请写在区域外*/");
                    temp.forEach(s -> result.add(fix(buildData, s)));
                    result.add("/*自动代码结束，自定义代码请写在区域外*/");
                }
            }
        }
        for (String line : buildData.imports) {
            result.add(1, "import %s;".formatted(line));
        }
        lines = result;
        FileUtil.writeLines(lines, file, "UTF-8");
    }
}
